package com.bootdo.common.aspect;

import static com.bootdo.common.utils.ShiroUtils.getUser;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.bootdo.common.utils.R;
import com.bootdo.common.utils.UdpGetClientMacAddr;
import com.bootdo.system.dao.WhitelistDao;
import com.bootdo.system.domain.WhitelistDO;

/**
 * @Desc
 * @date 2020/3/26
 *
 */
@Aspect
@Component
public class IpFilterAspect {
    private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);

    @Autowired
    private WhitelistDao whitelistMapper;

    @Pointcut("@annotation(com.bootdo.common.annotation.IpFilter)")
    public void ipPointCut() {
    }

    @Around("ipPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        //校验ip和mac地址
        boolean f = checkIp(point);
        // 执行方法
        if (f){
            return point.proceed();
        }
        return R.error("ip地址不一致，请联系管理员");
    }

    boolean checkIp(ProceedingJoinPoint joinPoint) {
        //验证是否为管理员
        List<Long> roleIds = getUser().getRoleIds();
        for (Long id : roleIds){
            if (64L == id){
                MethodSignature signature = (MethodSignature) joinPoint.getSignature();
                String className = joinPoint.getTarget().getClass().getName();
                String methodName = signature.getName();
                HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
                try {
                    String ip = getIp(request);
                    logger.info("请求方法" + className + "." + methodName + "()"  + "请求ip为：" + ip + "=========");
                    WhitelistDO whitelist = whitelistMapper.getByIpAndMac(ip, "");
                    if (whitelist != null) {
                        logger.info("请求方法" + className + "." + methodName + "()" + "ip为：" + ip + "=====校验成功=====");
                        return true;
                    }
                    logger.error("请求方法" + className + "." + methodName + "()" + "ip为：" + ip + "====校验失败====");
                    return false;
                } catch (Exception e) {
                    logger.error("请求方法" + className + "." + methodName + "()" + "ip为：" + getIp(request) + "====校验失败====");
                    return false;
                }
            }
        }
        return true;
    }

    private String getIp(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
    }


    public static String getMac(String ip) throws Exception {
        UdpGetClientMacAddr  udpGetClient = new UdpGetClientMacAddr(ip);
        return udpGetClient.getRemoteMacAddr();
    }

}
